﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using Microsoft.WindowsMobile.PocketOutlook;
using OutlookHub.Utils;

namespace OutlookHub.Models
{
    public enum TaskOrder
    {
        DueDate,
        StartDate,
        Subject,
        Priority
    }

    public class OutlookContext : IDisposable
    {
        private Dictionary<string, bool> selectedCategories = new Dictionary<string, bool>();
        private static OutlookContext context;
        private OutlookSession session;
        private List<string> categories;

        #region ctor / dtor

        public OutlookContext()
            : base()
        {
            CategoriesFilter = string.Empty;
        }

        public void Dispose()
        {
            if (session != null)
            {
                session.Dispose();
                session = null;
            }
            GC.SuppressFinalize(this);
        }


        ~OutlookContext()
        {
            Dispose();
        }

        #endregion


        public TaskOrder TaskOrder { get; set; }

        public static OutlookContext Context
        {
            get
            {                
                if (context == null) context = new OutlookContext();
                return context;
            }
        }

        public OutlookSession Session
        {
            get
            {
                if (session == null) session = new OutlookSession();
                return session;
            }
        }

        public IEnumerable<Task> AllTasks
        {
            get
            {
                return Session.Tasks.Items.Cast<Task>();
            }
        }

        public IEnumerable<Task> TodayTasks
        {
            get
            {
                DateTime now = DateTime.Now.Date;
                return AllTasks.Where(t => !t.Complete && (t.StartDate.IsNull() || t.StartDate <= now || t.DueDate <= now));
            }
        }

        public string CategoriesFilter { get; private set; }

        public IEnumerable<string> SelectedCategories
        {
            get { return selectedCategories.Keys; }
            set
            {
                selectedCategories = value.Distinct().ToDictionary(k => k, v => true);
                CategoriesFilter = SelectedCategories.AsCommaDelimitedString();
            }
        }

        public bool IsCategoryInFilter(string category)
        {
            return selectedCategories.ContainsKey(category);
        }

        public IList<string> Categories
        {
            get
            {
                if (categories == null) categories = GetCategories();
                return categories;
            }
        }

        private List<string> GetCategories()
        {
            var fromTasks = from t in Session.Tasks.Items.Cast<Task>() from c in t.Categories.SplitByComma() select c;
            var merged = fromTasks.Distinct().OrderBy(c => c).ToList();
            return merged;
        }

        public void Invalidate()
        {
            categories = null;
        }

        public static void Close()
        {
            if (context != null)
            {
                context.Dispose();
                context = null;
            }
        }


        public void AddCategory(string category)
        {
            if (categories == null) categories = GetCategories();
            int index = categories.BinarySearch(category);
            if (index < 0) index = ~index;
            categories.Insert(index, category);
        }
    }
}
